﻿using Newtonsoft.Json;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace MyFurion.Unility.Generic
{
    /// <summary>
    /// 工具通用类
    /// </summary>
    public static class ToolUtil
    {
        /// <summary>
        /// 要分割的字符串 eg: 1,3,10,00
        /// </summary>
        /// <param name="str"></param>
        /// <param name="split">分割的字符串</param>
        /// <returns></returns>
        public static long[] SpitLongArrary(string str, char split = ',')
        {
            if (string.IsNullOrEmpty(str)) { return Array.Empty<long>(); }
            str = str.TrimStart(split).TrimEnd(split);
            string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
            long[] infoIdss = Array.ConvertAll(strIds, s => long.Parse(s));
            return infoIdss;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="split"></param>
        /// <returns></returns>
        public static int[] SpitIntArrary(string str, char split = ',')
        {
            if (string.IsNullOrEmpty(str)) { return Array.Empty<int>(); }
            string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
            int[] infoIdss = Array.ConvertAll(strIds, s => int.Parse(s));
            return infoIdss;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="split"></param>
        /// <returns></returns>
        public static Guid[] SpitGuidArrary(string str, char split = ',')
        {
            if (string.IsNullOrEmpty(str)) { return Array.Empty<Guid>(); }
            str = str.TrimStart(split).TrimEnd(split);
            string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
            Guid[] infoIdss = Array.ConvertAll(strIds, s => Guid.Parse(s));
            return infoIdss;
        }

        /// <summary>
        /// 根据日期获取星期几
        /// </summary>
        public static string GetWeekByDate(DateTime dt)
        {
            var day = new[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
            return day[Convert.ToInt32(dt.DayOfWeek.ToString("d"))];
        }

        /// <summary>
        /// 得到这个月的第几周
        /// </summary>
        /// <param name="daytime">年月日</param>
        /// <returns>传递过来的时间是第几周</returns>
        public static int GetWeekNumInMonth(DateTime daytime)
        {
            int dayInMonth = daytime.Day;
            //本月第一天
            DateTime firstDay = daytime.AddDays(1 - daytime.Day);
            //本月第一天是周几
            int weekday = (int)firstDay.DayOfWeek == 0 ? 7 : (int)firstDay.DayOfWeek;
            //本月第一周有几天
            int firstWeekEndDay = 7 - (weekday - 1);
            //当前日期和第一周之差
            int diffday = dayInMonth - firstWeekEndDay;
            diffday = diffday > 0 ? diffday : 1;
            //当前是第几周,如果整除7就减一天
            int weekNumInMonth = ((diffday % 7) == 0
                ? (diffday / 7 - 1)
                : (diffday / 7)) + 1 + (dayInMonth > firstWeekEndDay ? 1 : 0);
            return weekNumInMonth;
        }
        /// <summary>
        /// 判断一个字符串是否为url
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsUrl(string str)
        {
            try
            {
                string Url = @"^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$";
                return Regex.IsMatch(str, Url);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }
        /// <summary>
        /// 获取枚举说明
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string GetDescription<TEnum>(TEnum enumData)
        {
            string description = "";
            if (enumData != null)
            {
                string name = enumData.ToString();
                if (!string.IsNullOrWhiteSpace(name))
                {
                    FieldInfo fieldInfo = enumData.GetType().GetField(name);
                    if (fieldInfo != null)
                    {
                        DescriptionAttribute attribute = Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute)) as DescriptionAttribute;
                        description=attribute?.Description;
                    }
                }
            }
            return description;
        }
        /// <summary>
        /// 获取枚举的Description
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum value)
        {
            return value.GetType().GetMember(value.ToString()).FirstOrDefault()?.GetCustomAttribute<DescriptionAttribute>()?.Description;
        }
        /// <summary>
        /// 将object对象转换为实体对象
        /// </summary>
        /// <typeparam name="T">实体对象类名</typeparam>
        /// <param name="asObject">object对象</param>
        /// <returns></returns>
        public static T ConvertObject<T>(object asObject) where T : new()
        {
            var josn = JsonConvert.SerializeObject(asObject);
            var t = JsonConvert.DeserializeObject<T>(josn);
            return t;
        }
        /// <summary>
        /// 判断实体类字段值是否全部为空
        /// </summary>
        /// <param name="obj">实体对象</param>
        /// <param name="ignoreFields">忽略字段</param>
        /// <returns></returns>
        public static bool IsPropNull(object obj, List<string> ignoreFields)
        {
            Type t = obj.GetType();
            PropertyInfo[] props = t.GetProperties();
            List<string> emptyList = new List<string>();
            foreach (PropertyInfo prop in props)
            {
                string itemName = prop.Name;
                if (!ignoreFields.Any(p => p == itemName))
                {
                    var itemValue = prop.GetValue(obj, null);
                    string typeName = prop.PropertyType.Name.ToLower();
                    if (typeName == "string" && itemValue != null)
                    {
                        if (string.IsNullOrWhiteSpace(itemValue.ToString()))
                        {
                            emptyList.Add(prop.Name);
                        }
                    }
                    else
                    {
                        if (itemValue == null)
                        {
                            emptyList.Add(prop.Name);
                        }
                    }
                }
            }
            return emptyList.Count() == (props.Length - ignoreFields.Count());
        }
        /// <summary>
        /// 计算文件大小
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string FormatFileSize(long size)
        {
            if (size < 1024)
            {
                return size.ToString() + " B";
            }

            if (size < 1024 * 1024)
            {
                return Math.Round((double)size / 1024, 2).ToString() + " KB";
            }

            if (size < 1024 * 1024 * 1024)
            {
                return Math.Round((double)size / 1024 / 1024, 2).ToString() + " MB";
            }
            else
            {
                return Math.Round((double)size / 1024 / 1024 / 1024, 2).ToString() + " GB";
            }
        }
        /// <summary>
        /// 获取相同实体类中字段值不同的字段名称
        /// </summary>
        /// <param name="sourceData"></param>
        /// <param name="destData"> </param>
        /// <param name="compareField">需要比较的字段名称</param>
        /// <returns></returns>
        public static List<string> CompareEntityDiff(object sourceData, object destData, List<string> compareField)
        {
            Type t = sourceData.GetType();
            PropertyInfo[] props = t.GetProperties();
            Type tdest = destData.GetType();
            PropertyInfo[] destprops = tdest.GetProperties();
            List<string> diffFieldList = new List<string>();
            foreach (PropertyInfo prop in props)
            {
                string fieldName = prop.Name;//字段名称
                if (compareField.Any(p => p == fieldName))
                {
                    var itemValue = prop.GetValue(sourceData, null) ?? "";
                    object destValue = "";
                    if (t.FullName == tdest.FullName)
                    {
                        destValue = prop.GetValue(destData, null) ?? "";
                    }
                    else
                    {
                        foreach (var destProp in destprops)
                        {
                            if (destProp.Name == fieldName)
                            {
                                destValue = destProp.GetValue(destData, null) ?? "";
                            }
                        }
                    }
                    //string typeName = prop.PropertyType.Name.ToLower();//字段类型
                    if (itemValue.ToString() != destValue.ToString())
                    {
                        diffFieldList.Add(fieldName);
                    }
                }
            }
            return diffFieldList;
        }
    }
}
